﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.IO;

namespace Generator.Helpers
{
    /// <summary>
    /// Cette classe représente un Helper pour manipuler les éléments d'un fichier VSTemplate
    /// </summary>
    internal class VSTemplateHelper
    {
        #region Const

        /// <summary>
        /// Namespace dans le fichier VSTemplate
        /// </summary>
        internal const string NAMESPACE = "{http://schemas.microsoft.com/developer/vstemplate/2005}";

        internal const string MSBUILD_NAMESPACE = "{http://schemas.microsoft.com/developer/msbuild/2003}";

        internal const string SOLUTION_TEMPLATE_NAME = "SolutionTemplate.vstemplate";

        internal const string PROJECT_TEMPLATE_NAME = "ProjectTemplate.vstemplate";

        internal const string TEMPLATE_DATA = NAMESPACE + "TemplateData";

        internal const string TEMPLATE_CONTENT = NAMESPACE + "TemplateContent";

        internal const string PROJECT_EXTENSION = ".csproj";

        internal const string VSTEMPLATE_EXTENSION = ".vstemplate";

        #endregion

        private TextReplaceHelper textReplaceHelper;

        public VSTemplateHelper()
        {
            this.textReplaceHelper = new TextReplaceHelper();
        }

        #region ReadDocument Method

        /// <summary>
        /// Cette méthode permet de lire un fichier VSTemplate de base
        /// </summary>
        /// <param name="filename">Fichier</param>
        /// <returns>XDocument</returns>
        internal XDocument ReadDocument(string filename)
        {
            XDocument document = null;
            if (File.Exists(filename))
            {
                var contentTemplate = File.ReadAllText(filename);
                document = XDocument.Parse(contentTemplate);
            }
            return document;
        }

        #endregion

        #region CreateProjectElement Method

        internal XElement CreateProjectElement(string filename)
        {
            var element = new XElement(NAMESPACE + "Project");
            element.Add(new XAttribute("TargetFileName", this.textReplaceHelper.ReplaceNamespace(filename)));
            element.Add(new XAttribute("File", filename));
            element.Add(new XAttribute("ReplaceParameters", "true"));
            return element;
        }

        #endregion

        #region CreateProjectItemElement Method

        internal XElement CreateProjectItemElement(string shortfilename, string filename)
        {
            FileHelper helper = new FileHelper();
            var element = new XElement(NAMESPACE + "ProjectItem");
            element.Add(new XAttribute("ReplaceParameters", helper.CheckFilenameExtension(shortfilename).ToString().ToLower()));
            element.Add(new XAttribute("TargetFileName", shortfilename));
            element.Value = filename;
            return element;
        }

        #endregion

        #region CreateFolderElement Method

        internal XElement CreateFolderElement(string foldername)
        {
            var element = new XElement(NAMESPACE + "Folder");
            element.Add(new XAttribute("Name", foldername));
            element.Add(new XAttribute("TargetFolderName", foldername));
            return element;
        }

        #endregion

        #region CreateSolutionFolderElement Method

        internal XElement CreateSolutionFolderElement(string foldername)
        {
            var element = new XElement(NAMESPACE + "SolutionFolder");
            element.Add(new XAttribute("Name", foldername));
            return element;
        }

        #endregion

        #region CreateProjectTemplateLinkElement Method

        internal XElement CreateProjectTemplateLinkElement(string projectName, string folder)
        {
            var element = new XElement(NAMESPACE + "ProjectTemplateLink");
            element.Add(new XAttribute("ProjectName", this.textReplaceHelper.ReplaceNamespace(projectName.Replace(PROJECT_EXTENSION, ""))));
            element.Value = folder + "\\" + projectName.Replace(PROJECT_EXTENSION, VSTEMPLATE_EXTENSION);
            return element;
        }

        #endregion

        #region GetProjectInclude Method

        /// <summary>
        /// Cette méthode permet de récupérer l'ensemble de Include or Reference issu du Projet
        /// </summary>
        /// <param name="projectFilename">Nom du Fichier Project à parser</param>
        /// <returns>Liste des includes</returns>
        public List<string> GetProjectInclude(string projectFilename)
        {
            var result = new List<string>();
            var projectDocument = this.ReadDocument(projectFilename);

            // Parcours les ItemGroup
            foreach (var group in projectDocument.Root.Elements().Where(e => Convert.ToString(e.Name) == (MSBUILD_NAMESPACE + "ItemGroup")))
            {
                if (group.HasElements)
                {
                    foreach (var item in group.Elements().Where(e => Convert.ToString(e.Name) != (MSBUILD_NAMESPACE + "Reference")).Attributes("Include"))
                    {
                        result.Add(item.Value);
                    }
                }
            }

            return result;
        } 

        #endregion
                
    }
}
